home *** CD-ROM | disk | FTP | other *** search
- %------------ start of eq_out.ari --------------------------------------
- %
- %
- %
- %
- /* This module removes equalities from rule bodies and replaces them with
- patterns. As an example, the rule
-
- prdbms_goal(X) :-
- book( Authors, Title, Price, Publisher, Topic, Date),
- publisher(Name, Address),
- Publisher = Address,
- Topic = prolog,
- X =[ Authors, Title, Publisher, Address ]),
-
- is changed to
-
- prdbms_goal([_00CD,_00D1,_00D9,_00D9]) :-
- book(_00CD,_00D1,_00D5,_00D9,prolog,_00E1) ,
- publisher(_00F5,_00D9).
-
- Author: Rodger Knaus
- Instant Recall
- Box 30134
- 5900 Walton Rd.
- Bethesda, Md. 20814
- (301) 530-0898
-
- Note: trace_message is called for tracing purposes only in this file.
- You can either get trace_message as part of Prolog Tools from
- Instant Recall, or write your own, or use the dummy provided
- below.
-
- */
-
- trace_message(_):-!.
-
- %--------------- eq_out --------------------------------------------------
- /* This predicate removes equalities from rule bodies and replaces them with
- patterns. The first argument is an input rule, possibly containing
- equalities. The 2nd. argument is an equivalent rule with
- "assignment-statement-like" equality subgoals replaced by patterns.
- */
-
-
- eq_out( (Head :- Body) , New_clause ) :-
- % get the list of subgoals in the rule body
- get_rule_body_as_list( Body , Body_subgoal_list), !,
- % this is just a trace -- you can take it out
- trace_message([$Body_subgoal_list = $,Body_subgoal_list]), !,
- % carry out unifications that the equalities
- % express, when the left argument is a variable
- eq_out_hlpr( (Head :- Body), Body_subgoal_list), !,
- % remove those equalities from the list of subgoals
- % -- we have just done them at "compile time"è remove_equalities( Body_subgoal_list, List_without_equalities), !,
- % build the output rule
- build_clause( Head , List_without_equalities , New_clause).
-
- %--------------- eq_out_hlpr ---------------------------------------------
- /*
- Call: eq_out_hlpr( In_rule, Body_subgoal_list)
-
- Input args:
-
- In_rule = a Prolog goal (may be a rule)
-
- Body_subgoal_list = a list of the subgoals in the body of
- In_rule
-
-
- */
- % nothing to do if the subgoal list is empty.
- eq_out_hlpr( In_rule, []) :-
- trace_message([$ e eq_out_hlpr empty set rule$]),
- !.
-
- % if the first subgoal is an assignment-like equality,
- % then call (execute) this unification
- eq_out_hlpr( In_rule, [Term | Terms]) :-
- trace_message([$ e eq_out_hlpr assignment rule$]),
- trace_message([$ Term =$, Term ]),
- trace_message([$ Terms =$, Terms ]),
- % test for an assignment-like equality,
- is_assignment( Term), !,
- trace_message([$ leading term is assignment $]),
- % force the unification expressed by Term
- call(Term),
- trace_message([$ a assignment rule = $,In_rule ]),
- % recurse
- eq_out_hlpr( In_rule, Terms).
-
- % otherwise, just go on to the remaining subgoals
- eq_out_hlpr( In_rule, [ _ | Terms]) :-
- trace_message([$ e eq_out_hlpr dflt rule$]),
- trace_message([$ Terms =$, Terms ]),
- % recurse
- eq_out_hlpr( In_rule, Terms).
-
- %--------------- is_assignment -------------------------------------------
- /* This predicate recognizes goals that are assignment-like equalities,
- <Variable > = < Term>. These goals, when executed, unify the
- Variable with the Term.
- */
-
- is_assignment( =(Var, Term)) :-
- var(Var).
-
-
- %--------------- get_rule_body_as_list -----------------------------------è/* This predicate returns a rule Body as a list of subgoals */
-
- get_rule_body_as_list( Body, Body_subgoal_list) :-
- % we do this by using build_conjunction " in reverse "
- build_conjunction( Body_subgoal_list, Body).
-
- %--------------- remove_equalities ---------------------------------------
- /* This predicate removes the equality goals from a list of goals. */
-
- % empty list contains no equalities
- remove_equalities( [] , [] ) :- !.
-
- % leave out the first subgoal in the input list if it is an
- % equality
- remove_equalities( [=(X,X) | Subgoals],
- Subgoals_without_equalities ) :-
- % and then make recursive call
- remove_equalities( Subgoals ,
- Subgoals_without_equalities).
-
- % otherwise include the first subgoal in the output,
- remove_equalities( [Subgoal | Subgoals],
- [Subgoal | Subgoals_without_equalities] ) :-
- % and then make recursive call
- remove_equalities( Subgoals ,
- Subgoals_without_equalities).
-
-
- %--------------- build_clause --------------------------------------------
- /* Given a rule head and a list of subgoals, this predicate builds a
- Prolog clause -- either a fact or rule, as appropriate.
- */
- % When there are no subgoals, use the " rule head " as a fact.
- build_clause( Head, [], Head) :- !.
-
- % Build a rule for the case where there is just 1 subgoal.
- build_clause( Head, [Subgoal], ( Head :- Subgoal ) ) :- !.
-
- % Build a rule with a conjunction of subgoals if there are more
- % than 1 subgoal
- build_clause( Head, Subgoals, ( Head :- And_of_Subgoals ) ) :-
- build_conjunction( Subgoals, And_of_Subgoals).
-
-
- %--------------- build_conjunction ---------------------------------------
-
- /*
- Call: build_conjunction( List, Conjunction)
-
- Purpose: convert between a list of goals and a conjunction of goals
-
- Input {Output} arguments:
-
- List = a list of terms
- è Output { Input} arguments
-
- Conjunction = the list of terms ANDed together.
-
- Success conditions:
-
- Succeeds whenever the 2nd arg. can be unified with the conjunction
- of the 1st arg., or the 1st. arg. with the list of goals contained
- in the 2nd. arg. conjunction.
-
- Note: This predicate works in either direction
-
- Aside for Programmers: The definition of this predicate is interesting,
- because the recursive rule has to come before the boundary cases.
- Intuitively, this is because the recursive rule is the most
- restrictive, containing 2 somewhat complex patterns.
-
- */
-
-
- % termination case for lists
- build_conjunction( List , Term ) :-
- not(var(List)),
- List = [ Term ],!.
-
- % AND of no items is always true
- build_conjunction( [], true):-!.
-
- % Here is the recursive rule for conjunctions.
- build_conjunction( [ Term | Terms ], ( Term , And_of_Terms)) :-
- build_conjunction( Terms , And_of_Terms),!.
-
- % Termination case for conjunctions
- build_conjunction( [ Term ], Term) :-
- not(var( Term)).
-
-
- %--------------- test predicate ------------------------------------------
-
- test :-
- % nl_log_to_file is an Instant Recall Prolog Tool that saves trace
- % messages to a file -- we have commented out this call, used for
- % debugging only
- % nl_log_to_file(log),
- eq_out(
- (prdbms_goal(X) :-
- book( Authors, Title, Price, Publisher, Topic, Date),
- publisher(Name, Address),
- Publisher = Name,
- Topic = prolog,
- X =[ Authors, Title, Publisher, Address ]),
- Out_rule),
- trace_message([$Out_rule = $, Out_rule ])
- ,
- % write out results without using trace_messageè nl, write($Resulting Predicate:$),
- nl, write(Out_rule)
- %
- % closing the log file is also commented out
- % ,
- % nl_close_log_file
- .
-
-
- %---------------- end of eq_out.ari ------------------------------------
-